package com.ddwl.goods.service;

import cn.hutool.core.collection.CollUtil;
import com.ddwl.common.constant.BaseEnum;
import com.ddwl.schema.bo.goods.QueryLimitTimePurGoodBo;
import com.ddwl.schema.bo.goods.ShoppingSkuVo;
import com.ddwl.schema.bo.goods.WbmShoppingSkuBo;
import com.ddwl.schema.bo.goods.retail.ShoppingCartPageBo;
import com.ddwl.schema.bo.goods.retail.ShoppingCartPageByShopBo;
import com.ddwl.schema.vo.goods.retail.ShoppingCartPageVo;
import org.springframework.util.CollectionUtils;
import cn.hutool.core.util.StrUtil;
import com.ddwl.common.constant.Constant;
import com.ddwl.common.exception.ParamException;
import com.ddwl.common.feign.api.ShopApi;
import com.ddwl.common.util.BeanConverUtils;
import com.ddwl.common.util.MySqlUtil;
import com.ddwl.goods.dao.*;
import com.ddwl.goods.dao.model.*;
import com.ddwl.goods.model.DiscountItem;
import com.ddwl.goods.model.DiscountItemSku;
import com.ddwl.goods.model.ItemTag;
import com.ddwl.goods.service.ItemService;
import com.ddwl.goods.service.ShoppingCartService;
import com.ddwl.schema.bo.base.PageBo;
import com.ddwl.schema.vo.base.PageVo;
import com.ddwl.schema.vo.goods.*;
import com.ddwl.schema.vo.shop.ShopVo;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.time.Instant;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 类ShoppingCartServerImpl.java的实现描述：购物车服务
 *
 * @author zach
 * @Date :2020-06-05 16:12.
 */
@Service
public class ShoppingCartService {

    @Resource
    private ShoppingCartDao shoppingCartDao;
    @Resource
    private ItemService itemService;
    @Resource
    private DiscountDao discountDao;
    @Resource
    private SkuDao skuDao;
    @Resource
    private ReserveDao reserveDao;
    @Resource
    private ShopApi shopApi;
    @Resource
    private ItemTagDao itemTagDao;
    @Resource
    private DiscountItemDao discountItemDao;
    @Resource
    private DiscountItemSkuDao discountItemSkuDao;
    @Resource
    private LimitTimePurGoodDao limitTimePurGoodDao;

    /**
     * 保存购物车
     * @param shoppingSkuVo
     * @param userId
     */
    public void userSaveShoppingCart(ShoppingSkuVo shoppingSkuVo, String userId, boolean qtyAdd) {
        ShoppingCart shoppingCart = BeanConverUtils.convertBean(shoppingSkuVo, ShoppingCart.class);
        shoppingCart.setUserId(userId);
        ShoppingCart shoppingCart1 = shoppingCartDao.selectBySkuCode(shoppingSkuVo.getSkuCode(), userId);
        if (shoppingCart1 != null) {
            shoppingCart.setId(shoppingCart1.getId());
            if (qtyAdd) {
                shoppingCart.setSkuQty(shoppingCart1.getSkuQty() + shoppingSkuVo.getSkuQty());
            } else {
                shoppingCart.setSkuQty(shoppingSkuVo.getSkuQty());
            }
            shoppingCartDao.updateByPrimaryKeySelective(shoppingCart);
        } else {
            if (StrUtil.isEmpty(shoppingSkuVo.getItemId())) {
                Sku skuVo = skuDao.findByBarCode(shoppingSkuVo.getSkuCode());
                ParamException.isNull(skuVo);
                shoppingCart.setItemId(skuVo.getItemId());
            }
            ItemVo itemVo = itemService.getItem(shoppingCart.getItemId());
            ParamException.isNull(itemVo, "商品不存在");
            shoppingCart.setShopId(itemVo.getShopId());
            shoppingCart.setShopName(itemVo.getShopName());
            shoppingCartDao.insert(shoppingCart);
        }
    }


    /**
     * 删除购物车商品单件
     *
     * @param skuId
     * @param userId
     */
    public void userRemoveShoppingCart(String skuId, String userId) {
        ShoppingCart shoppingCart1 = shoppingCartDao.selectBySkuCode(skuId, userId);
        ParamException.isNull(shoppingCart1);
        shoppingCartDao.deleteById(shoppingCart1.getId());
    }

    /**
     * 删除购物车商品多单件
     *
     * @param skuCodes
     * @param userId
     */
    public void userRemoveShoppingCart(List<String> skuCodes, String userId) {
        List<ShoppingCart> shoppingCarts = shoppingCartDao.selectBySkuCodes(skuCodes, userId);
        shoppingCartDao.deleteByIds(shoppingCarts.stream().map(ShoppingCart::getId).collect(Collectors.toList()));
    }

    /**
     * 清空用户购物车
     *
     * @param userId
     */
    public void userClearShoppingCart(String userId) {
        shoppingCartDao.clearUserCard(userId);
    }

    /**
     * 查询购物车列表
     *
     * @param userId
     * @return
     */
    public ShoppingCartListVo queryClearShoppingCartPage(String userId) {
        ShoppingCartListVo listVo = new ShoppingCartListVo();
        List<ShoppingCartVo> shoppingCartVos = BeanConverUtils.convertBeanList(shoppingCartDao.queryUserShoppingCart(userId), ShoppingCartVo.class);
        if (CollectionUtils.isEmpty(shoppingCartVos)) {
            return listVo;
        }
        generateShoppingCartVo(shoppingCartVos);
        listVo.setShoppingCartVos(shoppingCartVos);
        return listVo;
    }

    public PageVo<ShoppingCartPageVo> wbmPage(PageBo<ShoppingCartPageBo> pageBo, String userId) {
        PageHelper.startPage(pageBo.getPage(), pageBo.getPageSize(), MySqlUtil.orderBy(pageBo.getSort(), pageBo.isAsc()));
        PageInfo<ShoppingCartPageVo> info = new PageInfo<>(shoppingCartDao.getListGroupByShop(userId));
        List<ShoppingCartPageVo> list = info.getList();
        if (CollectionUtils.isEmpty(list)) {
            return new PageVo<>(info.getTotal(), pageBo.getPage(), pageBo.getPageSize(), new ArrayList<>());
        }
        List<String> shopList = list.stream().map(ShoppingCartPageVo::getShopId).collect(Collectors.toList());
        List<ShoppingCart> shoppingCarts = shoppingCartDao.getListByUserIdAndShop(shopList, userId);
        List<ShoppingCartVo> shoppingCartVos = BeanConverUtils.convertBeanList(shoppingCarts, ShoppingCartVo.class);
        List<ShopVo> shopVos = shopApi.getShopListByIds(shopList).getResult();
        newGenerateShoppingCartVo(shoppingCartVos);
        for (int i = 0; i < list.size(); i++) {
            ShoppingCartPageVo scpVo = list.get(i);
            List<ShoppingCartVo> shopItemList = new ArrayList<>();
            shoppingCartVos.forEach(shoppingCartVo -> {
                if (scpVo.getShopId().equals(shoppingCartVo.getShopId())) {
                    shopItemList.add(shoppingCartVo);
                }
            });
            shopVos.forEach(shopVo -> {
                if (scpVo.getShopId().equals(shopVo.getId())) {
                    scpVo.setStatus(shopVo.getStatus());
                    scpVo.setSystemStop(shopVo.getSystemStop());
                    scpVo.setShopName(shopVo.getName());
                }
            });
            if (CollUtil.isEmpty(shopItemList)) {
                list.remove(scpVo);
            } else {
                scpVo.setShoppingCartVoList(shopItemList);
            }
        }
        return new PageVo<>(info.getTotal(), pageBo.getPage(), pageBo.getPageSize(), list);
    }

    public PageVo<ShoppingCartVo> pageByShop(PageBo<ShoppingCartPageByShopBo> pageBo) {
        PageHelper.startPage(pageBo.getPage(), pageBo.getPageSize(), MySqlUtil.orderBy(pageBo.getSort(), pageBo.isAsc()));
        PageInfo<ShoppingCart> info = new PageInfo<>(shoppingCartDao.getListByShop(pageBo.getParam()));
        List<ShoppingCartVo> shoppingCartVos = BeanConverUtils.convertBeanList(info.getList(), ShoppingCartVo.class);
        generateShoppingCartVo(shoppingCartVos);
        return new PageVo<>(info.getTotal(), pageBo.getPage(), pageBo.getPageSize(), shoppingCartVos);
    }

    public void wbmSaveShoppingCar(WbmShoppingSkuBo wbmShoppingSkuBo, String userId) {
        ParamException.isTrue((StrUtil.isEmpty(wbmShoppingSkuBo.getItemId()) && StrUtil.isEmpty(wbmShoppingSkuBo.getSkuCode())), "请选择商品");
        if (StrUtil.isEmpty(wbmShoppingSkuBo.getSkuCode())) {
            List<Sku> skuList = skuDao.findByItemId(wbmShoppingSkuBo.getItemId(), BaseEnum.StatusEnum.ENABLE.getCode());
            ParamException.isTrue(CollectionUtils.isEmpty(skuList), "商品不存在");
            ParamException.isTrue(skuList.size() > 1, "请选择商品规格");
            wbmShoppingSkuBo.setSkuCode(skuList.get(0).getBarcode());
        }
        ShoppingSkuVo shoppingSkuVo = BeanConverUtils.convertBean(wbmShoppingSkuBo, ShoppingSkuVo.class);
        userSaveShoppingCart(shoppingSkuVo, userId, Boolean.FALSE);
    }

    private void generateShoppingCartVo(List<ShoppingCartVo> shoppingCartVos) {
        List<String> itemIds = shoppingCartVos.stream().map(ShoppingCartVo::getItemId).collect(Collectors.toList());
        List<ItemVo> itemVos = itemService.getByItemIds(itemIds);
        List<String> skuCodes = shoppingCartVos.stream().map(ShoppingCartVo::getSkuCode).collect(Collectors.toList());
        List<Sku> skus = skuDao.findByBarCodes(skuCodes);
        List<ItemDetailVo> listVo = BeanConverUtils.convertBeanList(itemVos, ItemDetailVo.class);
        for (ItemDetailVo vo : listVo) {
            //vo.setSkus(skus.stream().filter(sku -> vo.getId().equals(sku.getItemId())).map(sku -> BeanConverUtils.convertBean(sku, SkuVo.class)).collect(Collectors.toList()));
            List<Discount> discounts = discountDao.getItemDiscountByItemId(vo.getId());
            DiscountVo discountVo = new DiscountVo();
            Map<String, String> map = new HashMap<>();
            for (Discount discount : discounts) {
                map.put(discount.getDiscountNum(), discount.getDiscountValue());
            }
            discountVo.setDiscountMap(map);
            vo.setDiscountVo(discountVo);
            //普通商品后变成预约商品，需返回预约信息
            Reserve re = new Reserve();
            re.setItemId(vo.getId());
            Reserve reserve = reserveDao.selectOne(re);
            vo.setReserveVo(BeanConverUtils.convertBean(reserve, ReserveVo.class));
        }
        for (int i = 0; i < shoppingCartVos.size(); i++) {
            ShoppingCartVo shoppingCartVo = shoppingCartVos.get(i);
            Sku sku = skus.stream().filter(sku1 -> sku1.getBarcode().equals(shoppingCartVo.getSkuCode())).findFirst().orElse(null);
            if (sku == null) {
                shoppingCartVos.remove(shoppingCartVo);
                shoppingCartDao.deleteById(shoppingCartVo.getId());
                i--;
                continue;
            }
            ItemDetailVo itemDetailVo = listVo.stream().filter(itemVo -> itemVo.getId().equals(sku.getItemId())).findFirst().orElse(null);
            if (itemDetailVo == null) {
                shoppingCartVos.remove(shoppingCartVo);
                shoppingCartDao.deleteById(shoppingCartVo.getId());
                i--;
                continue;
            }
            itemDetailVo = BeanConverUtils.convertBean(itemDetailVo, ItemDetailVo.class);
            itemDetailVo.setSkus(CollUtil.newArrayList(BeanConverUtils.convertBean(sku, SkuVo.class)));
            itemDetailVo.setItemDesc(null);
            shoppingCartVo.setItemVo(itemDetailVo);
        }
    }

    private void newGenerateShoppingCartVo(List<ShoppingCartVo> shoppingCartVos) {
        List<String> skuCodes = shoppingCartVos.stream().map(ShoppingCartVo::getSkuCode).collect(Collectors.toList());
        List<Sku> skus = skuDao.findByBarCodes(skuCodes);
        if (CollUtil.isEmpty(skus)) {
            shoppingCartDao.deleteByIds(shoppingCartVos.stream().map(ShoppingCartVo::getId).collect(Collectors.toList()));
            return;
        }
        List<String> itemIds = skus.stream().map(Sku::getItemId).collect(Collectors.toList());
        List<ItemVo> itemVos = itemService.getByItemIds(itemIds);
        if (CollUtil.isEmpty(itemVos)) {
            shoppingCartDao.deleteByIds(shoppingCartVos.stream().map(ShoppingCartVo::getId).collect(Collectors.toList()));
            return;
        }

        List<DiscountItemSku> discountItemSkus = discountItemSkuDao.findListByBarcodes(skuCodes);

        QueryLimitTimePurGoodBo bo=new QueryLimitTimePurGoodBo();
        bo.setBarcodes(skuCodes);
        bo.setIsEffect(1);
        bo.setIsNow(Instant.now());
        List<LimitTimePurGood> limitTimePurGoods = limitTimePurGoodDao.queryGood(bo);

        List<ItemTag> itemTagList = itemTagDao.findByItemIds(itemIds);

        for (int i = 0; i < shoppingCartVos.size(); i++) {
            ShoppingCartVo shoppingCartVo = shoppingCartVos.get(i);
            Sku sku = skus.stream().filter(sku1 -> sku1.getBarcode().equals(shoppingCartVo.getSkuCode())).findFirst().orElse(null);
            if (sku == null) {
                shoppingCartVos.remove(shoppingCartVo);
                shoppingCartDao.deleteById(shoppingCartVo.getId());
                i--;
                continue;
            }
            ItemVo vo = itemVos.stream().filter(itemVo -> itemVo.getId().equals(sku.getItemId())).findFirst().orElse(null);
            if (vo == null) {
                shoppingCartVos.remove(shoppingCartVo);
                shoppingCartDao.deleteById(shoppingCartVo.getId());
                i--;
                continue;
            }
            ItemDetailVo itemDetailVo = BeanConverUtils.convertBean(vo, ItemDetailVo.class);
            itemDetailVo.setSkus(CollUtil.newArrayList(BeanConverUtils.convertBean(sku, SkuVo.class)));

            ShoppingCarDiscountSkuVo scdSkuVo = BeanConverUtils.convertBean(sku, ShoppingCarDiscountSkuVo.class);
            //商品打折信息
            if (BaseEnum.StatusEnum.ENABLE.getCode().equals(itemDetailVo.getDiscountFlag()) && CollUtil.isNotEmpty(discountItemSkus)) {
                DiscountItemSku dItemSku = discountItemSkus.stream().filter(diSku -> sku.getBarcode().equals(diSku.getBarcode())).findFirst().orElse(null);
                if (null != dItemSku) {
                    scdSkuVo.setDiscountPrice(dItemSku.getDiscountPrice());
                    scdSkuVo.setDiscount(dItemSku.getDiscount());
                    scdSkuVo.setItemCommission(dItemSku.getItemCommission());
                    scdSkuVo.setStock(dItemSku.getStock());
                }
            }
            //商品限时购信息
            if (BaseEnum.StatusEnum.ENABLE.getCode().equals(itemDetailVo.getLimitTimeFlag()) && CollUtil.isNotEmpty(limitTimePurGoods)) {
                LimitTimePurGood limitTimePurGood = limitTimePurGoods.stream().filter(diSku -> sku.getBarcode().equals(diSku.getBarcode())).findFirst().orElse(null);
                if(limitTimePurGood!=null){
                    scdSkuVo.setDiscountPrice(limitTimePurGood.getLimitPrice());
                    scdSkuVo.setRetailPrice(limitTimePurGood.getItemPrice());
                    scdSkuVo.setItemCommission(limitTimePurGood.getDistAmount());
                    scdSkuVo.setStock(limitTimePurGood.getLimitCount()-limitTimePurGood.getSaleCount());
                }
            }
            itemDetailVo.setShoppingCarSkuVo(scdSkuVo);
            //商品标签
            if (!CollectionUtils.isEmpty(itemTagList)) {
                List<ItemTag> tags = itemTagList.stream().filter(itemTag -> itemDetailVo.getId().equals(itemTag.getItemId())).collect(Collectors.toList());
                List<ItemTagVo> itemTagVos =BeanConverUtils.convertBeanList(tags, ItemTagVo.class);
                itemDetailVo.setItemTagList(CollUtil.isEmpty(itemTagVos) ? null : itemTagVos);
            }
            itemDetailVo.setItemDesc(null);
            shoppingCartVo.setItemVo(itemDetailVo);
        }
    }

    public Integer count(String userId) {
        return shoppingCartDao.count(userId);
    }

}
